/*
 *  $Id: SWTImageBasic.java 3 2008-11-18 20:02:30Z Nathaniel.Waisbrot $
    Copyright (C) 2008  Nathaniel Waisbrot

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package termint.gui;

import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;

import termint.gui.graphics.TilesImageBlock;
import termint.gui.vt.VT320;
import termint.gui.vt.VTElement;

/**
 * @author Nathaniel Waisbrot
 * This is a SWT wrapper around the VT320 class.  Add it as a widget, then insert raw terminal data
 * into it.  It parses the escape codes and displays the image.
 */
public class SWTImageBasic extends SWTTerm {
	private TilesImageBlock tiles;
	
	public void saveTiles() {
		tiles.saveData();
	}
	
	public SWTImageBasic(Composite parent, VT320 vt) {
		super(parent, vt);
		moreSetup();
	}
	
	public SWTImageBasic(Composite parent) {
		super(parent);
		moreSetup();
	}
	
	private void moreSetup() {
		tiles = new TilesImageBlock(getDisplay(), getBackground());
		this.setSize(getSize().x, getSize().y);
	}
	
	public Point getSize() {
		return new Point(convertWidth(vt.width + 1), convertHeight(vt.height + 1));
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.swt.events.PaintListener#paintControl(org.eclipse.swt.events.PaintEvent)
	 * 
	 * used to handle self-painting
	 */
	public void paintControl(PaintEvent e) {
		int x = vt.getCursorColumn();
		int y = vt.getCursorRow();
		for (int h = 1; h < vt.height-2; h++) {
			for (int w = 0; w < vt.width; w++) {
				VTElement elt = vt.elementAt(w, h);
				Image i = tiles.getImage(elt);
				e.gc.drawImage(i, convertWidth(w), convertHeight(h));
			}
		}
		e.gc.drawImage(tiles.getCursor(), convertWidth(x), convertHeight(y));
		e.gc.drawRectangle(1, 1, convertWidth(vt.width), convertHeight(vt.height));
	}
	
	/**
	 * Send data to the attached VT320
	 * @param s the string to send
	 */
	public void setData(String s) {
		vt.putString(s);
	}
	
	/**
	 * Convert a width in VT characters into a width in SWT's pixels
	 * @param w width in VT chars
	 * @return width in pixels
	 */
	public int convertWidth(int w) {
		return leftMargin + tiles.getTileWidth() * w;
	}
	
	/**
	 * Convert a height in VT characters into a width in SWT's pixels
	 * @param h height in VT chars
	 * @return height in pixels
	 */
	public int convertHeight(int h) {
		return topMargin + tiles.getTileHeight() * h;
	}

	@Override
	public VTElement tileAtPoint(Point p) {
		Double x = Math.floor(Double.valueOf((double)(p.x - leftMargin) / (double)tiles.getTileWidth()));
		Double y = Math.floor(Double.valueOf((double)(p.y - topMargin) / (double)tiles.getTileHeight()));
		return vt.elementAt(x.intValue(), y.intValue());
	}

	public void setTileByIndex(VTElement element, int index) {
		tiles.setImage(element, index);	
	}
	
	public void dispose() {
		super.dispose();
		tiles.dispose();
	}
}
